package com.farm.common.security;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.jwt.JWT;
import com.farm.common.config.JwtConfig;
import com.farm.kaiping.entity.FarmUser;
import com.farm.kaiping.service.SysOauthClientDetailsService;
import com.farm.kaiping.service.SysUserService;
import com.farm.common.util.JwtTokenUtil;
import com.farm.common.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class SecurityAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private JwtConfig jwtConfig;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysOauthClientDetailsService sysOauthClientDetailsService;

    @Autowired
    RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取 token
        String token = request.getHeader(jwtConfig.getTokenHeader());
        if (ObjectUtil.isNotEmpty(token)){
            if (token.startsWith(jwtConfig.getTokenHeaderPrefix())){
                try {
                    JWT jwt = jwtTokenUtil.parseToken(token);
                    // 判断是否有该用户的缓存信息,（登录存入缓存，注销清除缓存）
                    FarmUser userInfo;
                    userInfo = sysUserService.getCacheSysUserByUserId(Integer.parseInt(jwt.getPayload(JwtTokenUtil.SUBJECT).toString()));
                    // 用户是否授权
                    if (ObjectUtil.isNotEmpty(userInfo) || SecurityContextHolder.getContext().getAuthentication() == null) {
                        // 将User 封装到 securityContextHolder。 封装到securityContextHolder以后，其他过滤器就不会在拦截
                        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userInfo, null, userInfo.getAuthorities());
                        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                    String message = ObjectUtil.isNotEmpty(exception.getMessage()) ? exception.getMessage() : "非法访问：非法访问";
                    responseError(request, response, message);
                    return;
                }
            } else if (token.startsWith(jwtConfig.getTokenHeaderBasicPrefix())) {
                String replace = token.replace(jwtConfig.getTokenHeaderBasicPrefix(), "").replace(" ", "");
                String decrypt = BtoaEncode.decrypt(replace);
                String[] split = decrypt.split(":");
                if (split.length != 2){
                    responseError(request, response, "Token 验证失败");
                    return;
                }
                Boolean b = sysOauthClientDetailsService.verifyClient(split[0], split[1]);
                if (!b){
                    responseError(request, response, "Token 客户端验证失败");
                    return;
                }
            }
        }
        filterChain.doFilter(request, response);
    }

    void responseError(HttpServletRequest request, HttpServletResponse response, String message) {
        R<String> result = new R<>();
        result.setMsg(message);
        result.setCode(1001);
        SecurityServletResponse.responseProcessing(request, response, result, HttpStatus.HTTP_UNAUTHORIZED);
        return;
    }


}
